﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Windows.Controls.Primitives;
using System.Windows;
using System.ComponentModel;
using System.Diagnostics;

namespace Bixas.Tangibilis.Controls.Primitives
{
    public class TouchScrollBar : ScrollBar, ITouchCursorEvent, ITouchCursorEventThunk, ITouchElement
    {

        private TouchScrollBarAdapter _adapter;

        private static readonly DependencyPropertyKey IsTouchCursorOverPropertyKey;
        public static readonly DependencyProperty IsTouchCursorOverProperty;

        private static readonly DependencyPropertyKey IsTouchCursorPressedPropertyKey;
        public static readonly DependencyProperty IsTouchCursorPressedProperty;

        public TouchScrollBar()
            : base()
        {
            this._adapter = new TouchScrollBarAdapter(this);
        }

        static TouchScrollBar()
        {
            IsTouchCursorOverPropertyKey = DependencyProperty.RegisterReadOnly("IsTouchCursorOver", typeof(bool), typeof(TouchScrollBar), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(TouchScrollBar.OnIsTouchCursorOverPropertyChanged)));
            IsTouchCursorOverProperty = IsTouchCursorOverPropertyKey.DependencyProperty;

            IsTouchCursorPressedPropertyKey = DependencyProperty.RegisterReadOnly("IsTouchCursorPressed", typeof(bool), typeof(TouchScrollBar), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(TouchScrollBar.OnIsTouchCursorPressedPropertyChanged)));
            IsTouchCursorPressedProperty = IsTouchCursorPressedPropertyKey.DependencyProperty;

            EventManager.RegisterClassHandler(typeof(TouchScrollBar), TouchThumb.TouchDragStartedEvent, new TouchDragStartedEventHandler(TouchScrollBar.OnTouchThumbDragStarted));
            EventManager.RegisterClassHandler(typeof(TouchScrollBar), TouchThumb.TouchDragDeltaEvent, new TouchDragDeltaEventHandler(TouchScrollBar.OnTouchThumbDragDelta));
            EventManager.RegisterClassHandler(typeof(TouchScrollBar), TouchThumb.TouchDragCompletedEvent, new TouchDragCompletedEventHandler(TouchScrollBar.OnTouchThumbDragCompleted));

            FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(TouchScrollBar), new FrameworkPropertyMetadata(typeof(TouchScrollBar)));
        }

        protected override void OnPreviewMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
        {
            base.OnPreviewMouseLeftButtonDown(e);
        }
        private static void OnTouchThumbDragCompleted(object sender, TouchDragCompletedEventArgs e)
        {

        }

        private bool _hasScrolled;
        private double _previousValue;
        private Vector _lastDragPosition;

        private static void OnTouchThumbDragStarted(object sender, TouchDragStartedEventArgs e)
        {
            TouchScrollBar bar = sender as TouchScrollBar;
            if (bar != null)
            {
                Phydeaux.Utilities.Dynamic<ScrollBar>.Instance.Field<Double>.Setter.CreateDelegate("_previousValue").Invoke(bar, bar.Value);
                Phydeaux.Utilities.Dynamic<ScrollBar>.Instance.Field<bool>.Setter.CreateDelegate("_hasScrolled").Invoke(bar, false);
            }
        }

        private static void OnTouchThumbDragDelta(object sender, TouchDragDeltaEventArgs e)
        {
            TouchScrollBar bar = sender as TouchScrollBar;
            if (bar != null)
            {
                bar._lastDragPosition = Vector.Add(bar._lastDragPosition, new Vector(e.HorizontalChange, e.VerticalChange));
                bar.UpdateValueHack(e.HorizontalChange, e.VerticalChange);
            }

        }

        private void UpdateValueHack(double horizontalChange, double VerticalChange)
        {
            Phydeaux.Utilities.Dynamic<ScrollBar>.Instance.Procedure.Explicit<double, double>.CreateDelegate("UpdateValue").Invoke(this, horizontalChange, VerticalChange);

        }

        #region ITouchCursorEvent Members

        public event System.Windows.RoutedEventHandler TouchCursorDown
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorDownEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorDownEvent, value);
            }
        }

        public event System.Windows.RoutedEventHandler TouchCursorEnter
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorEnterEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorEnterEvent, value);
            }
        }

        public event System.Windows.RoutedEventHandler TouchCursorLeave
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorLeaveEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorLeaveEvent, value);
            }
        }

        public event System.Windows.RoutedEventHandler TouchCursorMove
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorMoveEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorMoveEvent, value);
            }
        }

        public event System.Windows.RoutedEventHandler TouchCursorUp
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorUpEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorUpEvent, value);
            }
        }

        public event System.Windows.RoutedEventHandler TouchCursorPreviewDown
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorPreviewDownEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorPreviewDownEvent, value);
            }
        }

        public event System.Windows.RoutedEventHandler TouchCursorPreviewMove
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorPreviewMoveEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorPreviewMoveEvent, value);
            }
        }

        public event System.Windows.RoutedEventHandler TouchCursorPreviewUp
        {
            add
            {
                this.AddHandler(TouchCursorEvents.TouchCursorPreviewUpEvent, value, false);
            }
            remove
            {
                this.RemoveHandler(TouchCursorEvents.TouchCursorPreviewUpEvent, value);
            }
        }
        #endregion

        #region ITouchCursorEventThunk Members

        public void OnTouchCursorDownThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorDown(e);
        }

        public void OnTouchCursorEnterThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorEnter(e);
        }

        public void OnTouchCursorLeaveThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorLeave(e);
        }

        public void OnTouchCursorMoveThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorMove(e);
        }

        public void OnTouchCursorUpThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorUp(e);
        }

        public void OnTouchCursorPreviewDownThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorPreviewDown(sender, e);
        }

        public void OnTouchCursorPreviewMoveThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorPreviewMove(sender, e);
        }

        public void OnTouchCursorPreviewUpThunk(object sender, System.Windows.RoutedEventArgs e)
        {
            this._adapter.OnTouchCursorPreviewUp(sender, e);
        }

        #endregion

        private static void OnIsTouchCursorOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TouchScrollBar)d).OnTouchCursorOverChanged(e);
        }

        protected virtual void OnTouchCursorOverChanged(DependencyPropertyChangedEventArgs e)
        {
        }

        private static void OnIsTouchCursorPressedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TouchScrollBar)d).OnTouchCursorPressedChanged(e);
        }

        protected virtual void OnTouchCursorPressedChanged(DependencyPropertyChangedEventArgs e)
        {
        }

        #region ITouchElement Members

        [Bindable(true), Category("Appearance"), Browsable(false)]
        bool ITouchElement.IsTouchCursorOver
        {
            get
            {
                return (bool)base.GetValue(IsTouchCursorOverProperty);
            }
            set
            {
                if (value)
                {
                    base.SetValue(IsTouchCursorOverPropertyKey, value);
                }
                else
                {
                    base.ClearValue(IsTouchCursorOverPropertyKey);
                }
            }
        }

        [Bindable(true), Category("Appearance"), Browsable(false)]
        bool ITouchElement.IsTouchCursorPressed
        {
            get
            {
                return (bool)base.GetValue(IsTouchCursorPressedProperty);
            }
            set
            {
                base.SetValue(IsTouchCursorPressedPropertyKey, value);
            }
        }

        #endregion
    }
}
